package com.aw.baselib.util.pictureutil

import android.Manifest
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.provider.MediaStore
import android.widget.ImageView
import androidx.fragment.app.Fragment
import com.aw.baselib.util.pictureutil.GlideUtils.Companion.createGlideEngine
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.luck.lib.camerax.SimpleCameraX
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.PictureMimeType
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.engine.CompressFileEngine
import com.luck.picture.lib.engine.CropFileEngine
import com.luck.picture.lib.engine.VideoPlayerEngine
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnCameraInterceptListener
import com.luck.picture.lib.interfaces.OnExternalPreviewEventListener
import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener
import com.luck.picture.lib.interfaces.OnRecordAudioInterceptListener
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.luck.picture.lib.permissions.PermissionChecker
import com.luck.picture.lib.permissions.PermissionResultCallback
import com.luck.picture.lib.utils.MediaUtils
import com.luck.picture.lib.utils.ToastUtils
import com.yalantis.ucrop.UCrop
import com.yalantis.ucrop.UCropImageEngine
import top.zibin.luban.Luban
import top.zibin.luban.OnNewCompressListener
import java.io.File

/**
 * @author: zzw
 * @Description:
 * @Date: 2022/9/21 21:37
 */
object PictureUtils {
    /**
     * 打开摄像头 拍照
     *
     * @param context
     * @param isRotateImage                   true 前置 false 后置
     * @param onPictureSelectorResultListener 回调
     */
    fun openCamera(
        context: Context,
        isRotateImage: Boolean,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        openCamera(
            context,
            SelectMimeType.ofImage(),
            isRotateImage,
            onPictureSelectorResultListener
        )
    }

    /**
     * 打开摄像头 录制视频
     *
     * @param context
     * @param isRotateImage                   true 前置 false 后置
     * @param onPictureSelectorResultListener 回调
     */
    fun openVideo(
        context: Context,
        isRotateImage: Boolean,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        openCamera(
            context,
            SelectMimeType.ofVideo(),
            isRotateImage,
            onPictureSelectorResultListener
        )
    }

    /**
     * 打开摄像头
     *
     * @param context                         上下文
     * @param onPictureSelectorResultListener 回调
     */
    fun openCamera(
        context: Context,
        openCamera: Int,
        isRotateImage: Boolean,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        PictureSelector.create(context).openCamera(openCamera).isCameraAroundState(isRotateImage)
            .setVideoThumbnailListener(
                VideoThumbListener(context)
            ).setCompressEngine(
            CompressFileEngine { context1: Context?, source: ArrayList<Uri>?, call: OnKeyValueResultCallbackListener? ->
                Luban.with(context1).load(source).ignoreBy(100)
                    .setCompressListener(object : OnNewCompressListener {
                        override fun onStart() {}
                        override fun onSuccess(source: String, compressFile: File) {
                            call?.onCallback(source, compressFile.absolutePath)
                        }

                        override fun onError(source: String, e: Throwable) {
                            call?.onCallback(source, null)
                        }
                    }).launch()
            }).forResult(object : OnResultCallbackListener<LocalMedia> {
            override fun onResult(result: ArrayList<LocalMedia>) {
                onPictureSelectorResultListener.onResult(result)
            }

            override fun onCancel() {}
        })
    }

    /**
     * 设置头像
     *
     * @param mContext
     * @param selectResult                    结果
     * @param onPictureSelectorResultListener 结果回调
     */
    fun createAvatar(
        mContext: Context?,
        selectResult: ArrayList<LocalMedia?>?,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        create(
            mContext,
            SelectMimeType.ofImage(),
            selectResult,
            1,
            1,
            true,
            onPictureSelectorResultListener
        )
    }

    /**
     * 选择单张图片
     *
     * @param mContext
     * @param selectResult                    结果
     * @param onPictureSelectorResultListener 结果回调
     */
    fun createImageMin(
        mContext: Context?,
        selectResult: ArrayList<LocalMedia?>?,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        create(
            mContext,
            SelectMimeType.ofImage(),
            selectResult,
            1,
            1,
            false,
            onPictureSelectorResultListener
        )
    }

    /**
     * 选择多张图片
     *
     * @param mContext
     * @param selectResult                    结果
     * @param selectMax                       最多选择
     * @param onPictureSelectorResultListener 结果回调
     */
    fun createImageMax(
        mContext: Context?,
        selectMax: Int,
        selectResult: ArrayList<LocalMedia?>?,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        create(
            mContext,
            SelectMimeType.ofImage(),
            selectResult,
            1,
            selectMax,
            true,
            onPictureSelectorResultListener
        )
    }

    /**
     * 选择单个视频
     *
     * @param mContext
     * @param selectResult                    结果
     * @param onPictureSelectorResultListener 结果回调
     */
    fun createVideo(
        mContext: Context?,
        selectResult: ArrayList<LocalMedia?>?,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        create(
            mContext,
            SelectMimeType.ofVideo(),
            selectResult,
            1,
            1,
            false,
            onPictureSelectorResultListener
        )
    }

    /**
     * 选择单个音频
     *
     * @param mContext
     * @param selectResult                    结果
     * @param onPictureSelectorResultListener 结果回调
     */
    fun createAudio(
        mContext: Context?,
        selectResult: ArrayList<LocalMedia?>?,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        create(
            mContext,
            SelectMimeType.ofAudio(),
            selectResult,
            1,
            1,
            false,
            onPictureSelectorResultListener
        )
    }

    /**
     * 选择 媒体 图片 视频 音频
     *
     * @param mContext
     * @param selectResult                    结果
     * @param onPictureSelectorResultListener 结果回调
     */
    fun createPicture(
        mContext: Context?,
        selectResult: ArrayList<LocalMedia?>?,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        create(
            mContext,
            SelectMimeType.ofAll(),
            selectResult,
            1,
            1,
            false,
            onPictureSelectorResultListener
        )
    }

    /**
     * 默认设置
     *
     * @param mContext
     * @param selectMimeType                  结果
     * @param selectResult                    结果
     * @param selectMin                       最少选择
     * @param selectMax                       最多选择
     * @param isCrop                          是否剪裁
     * @param onPictureSelectorResultListener 结果回到
     */
    fun create(
        mContext: Context?,
        selectMimeType: Int,
        selectResult: ArrayList<LocalMedia?>?,
        selectMin: Int,
        selectMax: Int,
        isCrop: Boolean,
        onPictureSelectorResultListener: OnPictureSelectorResultListener
    ) {
        PictureSelector.create(mContext).openGallery(selectMimeType).isDisplayCamera(false)
            .setMaxSelectNum(selectMax).setCropEngine(
            getCropFileEngine(isCrop)
        ).setMinSelectNum(selectMin)
            .setFilterVideoMaxSecond(if (selectMimeType == SelectMimeType.ofVideo()) 60 else 60 * 10)
            .setFilterVideoMinSecond(5)
            .setRecordVideoMaxSecond(if (selectMimeType == SelectMimeType.ofVideo()) 60 else 60 * 10)
            .setRecordVideoMinSecond(5).setFilterMaxFileSize((100 * 1024 * 1024).toLong())
            .setCameraInterceptListener(
                MeOnCameraInterceptListener()
            ).isFilterSizeDuration(true).setSelectedData(selectResult)
            .setRecordAudioInterceptListener(
                MeOnRecordAudioInterceptListener()
            ).setCompressEngine(
            CompressFileEngine { context: Context?, source: ArrayList<Uri>?, call: OnKeyValueResultCallbackListener? ->
                Luban.with(context).load(source).ignoreBy(100)
                    .setCompressListener(object : OnNewCompressListener {
                        override fun onStart() {}
                        override fun onSuccess(source: String, compressFile: File) {
                            call?.onCallback(source, compressFile.absolutePath)
                        }

                        override fun onError(source: String, e: Throwable) {
                            call?.onCallback(source, null)
                        }
                    }).launch()
            }).setImageEngine(createGlideEngine())
            .forResult(object : OnResultCallbackListener<LocalMedia> {
                override fun onResult(result: ArrayList<LocalMedia>) {
                    for (media in result) {
                        if (media.width == 0 || media.height == 0) {
                            if (PictureMimeType.isHasImage(media.mimeType)) {
                                val imageExtraInfo = MediaUtils.getImageSize(mContext, media.path)
                                media.width = imageExtraInfo.width
                                media.height = imageExtraInfo.height
                            } else if (PictureMimeType.isHasVideo(media.mimeType)) {
                                val videoExtraInfo = MediaUtils.getVideoSize(mContext, media.path)
                                media.width = videoExtraInfo.width
                                media.height = videoExtraInfo.height
                            }
                        }
                        //                            LogUtils.e("文件名: " + media.getFileName() + "\n" +
//                                    "是否压缩:" + media.isCompressed() + "\n" +
//                                    "压缩路径:" + media.getCompressPath() + "\n" +
//                                    "初始路径:" + media.getPath() + "\n" +
//                                    "绝对路径:" + media.getRealPath() + "\n" +
//                                    "是否裁剪:" + media.isCut() + "\n" +
//                                    "裁剪路径:" + media.getCutPath() + "\n" +
//                                    "是否开启原图:" + media.isOriginal() + "\n" +
//                                    "原图路径:" + media.getOriginalPath() + "\n" +
//                                    "沙盒路径:" + media.getSandboxPath() + "\n" +
//                                    "水印路径:" + media.getWatermarkPath() + "\n" +
//                                    "视频缩略图:" + media.getVideoThumbnailPath() + "\n" +
//                                    "原始宽高: " + media.getWidth() + "x" + media.getHeight() + "\n" +
//                                    "裁剪宽高: " + media.getCropImageWidth() + "x" + media.getCropImageHeight() + "\n" +
//                                    "文件大小: " + PictureFileUtils.formatAccurateUnitFileSize(media.getSize()) + "\n" +
//                                    "文件大小: " + media.getSize() + "\n" +
//                                    "文件时长: " + media.getDuration()
//                            );
                    }
                    onPictureSelectorResultListener.onResult(result)
                }

                override fun onCancel() {}
            })
    }

    /**
     * 查看图片大图
     *
     * @param mContext
     * @param position
     * @param localMedia
     */
    fun openImage(mContext: Context?, position: Int, localMedia: ArrayList<LocalMedia?>?) {
        PictureSelector.create(mContext).openPreview().isHidePreviewDownload(true).setImageEngine(
            createGlideEngine()
        ).setExternalPreviewEventListener(object : OnExternalPreviewEventListener {
            override fun onPreviewDelete(position: Int) {}
            override fun onLongPressDownload(context: Context, media: LocalMedia): Boolean {
                return false
            }
        }).startActivityPreview(position, false, localMedia)
    }

    fun openImage(mContext: Context?, position: Int, imageUrl: String) {
        val localMedia = ArrayList<LocalMedia>()
        for (url in imageUrl.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
            localMedia.add(LocalMedia.generateHttpAsLocalMedia(url))
        }
        PictureSelector.create(mContext).openPreview().setImageEngine(createGlideEngine())
            .setExternalPreviewEventListener(object : OnExternalPreviewEventListener {
                override fun onPreviewDelete(position: Int) {}
                override fun onLongPressDownload(context: Context, media: LocalMedia): Boolean {
                    return false
                }
            }).startActivityPreview(position, false, localMedia)
    }
    /**
     * 预览视频
     *
     * @param mContext
     * @param position
     * @param localMedia
     */
    /**
     * 预览视频
     *
     * @param mContext
     * @param position
     * @param localMedia
     */
    @JvmOverloads
    fun openVideo(
        mContext: Context?,
        position: Int,
        localMedia: ArrayList<LocalMedia?>?,
        videoPlayerEngine: VideoPlayerEngine<*>? = null
    ) {
        PictureSelector.create(mContext).openPreview().setImageEngine(createGlideEngine())
            .setVideoPlayerEngine(videoPlayerEngine).isAutoVideoPlay(true)
            .setExternalPreviewEventListener(object : OnExternalPreviewEventListener {
                override fun onPreviewDelete(position: Int) {}
                override fun onLongPressDownload(context: Context, media: LocalMedia): Boolean {
                    return false
                }
            }).startActivityPreview(position, false, localMedia)
    }

    /**
     * 裁剪引擎
     *
     * @return
     */
    private fun getCropFileEngine(isCrop: Boolean): ImageFileCropEngine? {
        return if (isCrop) ImageFileCropEngine() else null
    }

    /**
     * 配制UCrop，可根据需求自我扩展
     *
     * @return
     */
    private fun buildOptions(): UCrop.Options {
        val options = UCrop.Options()
        options.setHideBottomControls(true)
        options.setFreeStyleCropEnabled(true)
        options.setShowCropFrame(true)
        options.setShowCropGrid(false)
        options.setCircleDimmedLayer(false)
        options.withAspectRatio(1f, 1f)
        options.isCropDragSmoothToCenter(false)
        options.setMaxScaleMultiplier(100f)
        return options
    }

    /**
     * 启动录音意图
     *
     * @param fragment
     * @param requestCode
     */
    private fun startRecordSoundAction(fragment: Fragment, requestCode: Int) {
        val recordAudioIntent = Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION)
        if (recordAudioIntent.resolveActivity(fragment.requireActivity().packageManager) != null) {
            fragment.startActivityForResult(recordAudioIntent, requestCode)
        } else {
            ToastUtils.showToast(fragment.context, "The system is missing a recording component")
        }
    }

    /**
     * 自定义裁剪
     */
    private class ImageFileCropEngine : CropFileEngine {
        override fun onStartCrop(
            fragment: Fragment,
            srcUri: Uri,
            destinationUri: Uri,
            dataSource: ArrayList<String>,
            requestCode: Int
        ) {
            val options = buildOptions()
            val uCrop = UCrop.of(srcUri, destinationUri, dataSource)
            uCrop.withOptions(options)
            uCrop.setImageEngine(object : UCropImageEngine {
                override fun loadImage(context: Context, url: String, imageView: ImageView) {
                    Glide.with(context).load(url).override(180, 180).into(imageView)
                }

                override fun loadImage(
                    context: Context,
                    url: Uri,
                    maxWidth: Int,
                    maxHeight: Int,
                    call: UCropImageEngine.OnCallbackListener<Bitmap>
                ) {
                    Glide.with(context).asBitmap().load(url).override(maxWidth, maxHeight)
                        .into(object : CustomTarget<Bitmap>() {
                            override fun onResourceReady(
                                resource: Bitmap,
                                transition: Transition<in Bitmap>?
                            ) {
                                if (call != null) {
                                    call.onCall(resource)
                                }
                            }

                            override fun onLoadCleared(placeholder: Drawable?) {
                                if (call != null) {
                                    call.onCall(null)
                                }
                            }
                        })
                }
            })
            uCrop.start(fragment.requireActivity(), fragment, requestCode)
        }
    }

    interface OnPictureSelectorResultListener {
        fun onResult(result: ArrayList<LocalMedia>?)
    }

    /**
     * 自定义拍照
     */
    private class MeOnCameraInterceptListener : OnCameraInterceptListener {
        override fun openCamera(fragment: Fragment, cameraMode: Int, requestCode: Int) {
            val camera = SimpleCameraX.of()
            camera.isAutoRotation(true)
            camera.setCameraMode(cameraMode)
            camera.setVideoFrameRate(50)
            camera.setVideoBitRate(5 * 1024 * 1024)
            camera.isDisplayRecordChangeTime(true)
            camera.isManualFocusCameraPreview(true)
            camera.isZoomCameraPreview(true)
            camera.setImageEngine { context: Context?, url: String?, imageView: ImageView? ->
                Glide.with(
                    context!!
                ).load(url).into(imageView!!)
            }
            camera.start(fragment.requireActivity(), fragment, requestCode)
        }
    }

    /**
     * 录音回调事件
     */
    private class MeOnRecordAudioInterceptListener : OnRecordAudioInterceptListener {
        override fun onRecordAudio(fragment: Fragment, requestCode: Int) {
            val recordAudio = arrayOf(Manifest.permission.RECORD_AUDIO)
            if (PermissionChecker.isCheckSelfPermission(fragment.context, recordAudio)) {
                startRecordSoundAction(fragment, requestCode)
            } else {
                PermissionChecker.getInstance().requestPermissions(
                    fragment,
                    arrayOf(Manifest.permission.RECORD_AUDIO),
                    object : PermissionResultCallback {
                        override fun onGranted() {
                            startRecordSoundAction(fragment, requestCode)
                        }

                        override fun onDenied() {}
                    })
            }
        }
    }
}